#include "sgl_draw_rect.h"
#include "stdio.h"


void sgl_draw_rect_solid(sgl_surf_t *surf, sgl_rect_t rect, sgl_color_t color)
{
    sgl_draw_area_color(surf, rect.x1, rect.y1, rect.x2, rect.y2, color);
}

void sgl_draw_rect_hollow(sgl_surf_t *surf, sgl_rect_t rect, sgl_color_t color)
{
    sgl_draw_hline(surf, rect.x1, rect.y1, rect.x2 - rect.x1, color);
    sgl_draw_hline(surf, rect.x1, rect.y2, rect.x2 - rect.x1, color);
    sgl_draw_vline(surf, rect.x1, rect.y1, rect.y2 - rect.y1, color);
    sgl_draw_vline(surf, rect.x2, rect.y1, rect.y2 - rect.y1 + 1, color);
}

void sgl_draw_round_rect_solid(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    int height = cy2 - cy1;
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_hline(surf, cx1 - path[y] + 1, cy2 + y - 1,  (path[y] - 1)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - path[y] + 1, cy1 - y,  (path[y] - 1)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy1 - path[y] + 1, (y)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy2 + path[y] - 2, (y)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
        }
    }
    while(height -- ) {
        sgl_draw_hline(surf, rect.x1 + 1, height + cy1, rect.x2 - rect.x1 - 2, fg_color);
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y1, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 1, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, cy1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cy1, cy2 - cy1, edge_color);
#else
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = rect.y2-rect.y1-diameter;
    int edge_wieth = rect.x2-rect.x1-diameter;
    int edge_height_count = edge_height;
    sgl_draw_hline(surf, cx1, rect.y1, edge_wieth + 1, edge_color);
    sgl_draw_hline(surf, cx1, rect.y2-1, edge_wieth + 1, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);
        sgl_draw_hline(surf, cx1-y, cy1-x+1, cx2 - cx1 + 2*y, fg_color);
        sgl_draw_hline(surf, cx1-y, cy2+x-2, cx2 - cx1 + 2*y, fg_color);
        sgl_draw_hline(surf, cx1-x+1, cy1-y, cx2 - cx1 + 2*x - 2, fg_color); 
        sgl_draw_hline(surf, cx1-x+1, cy2+y-1,cx2 -cx1 + 2*x - 2, fg_color);
        f += ddF_x + 1;
    }
    if ( edge_height_count > 0) {
        do {
            sgl_draw_hline(surf, rect.x1 + 1, cy2 - edge_height_count, edge_wieth + diameter - 2, fg_color);
        }while(edge_height_count -- );
        sgl_draw_vline(surf, rect.x1, cy1, edge_height, edge_color);
        sgl_draw_vline(surf, rect.x2 - 1, cy1, edge_height, edge_color);
    }
#endif
}


void sgl_draw_round_rect_hollow(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 -  mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
        }
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y1, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y1 + 1, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 1, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 2, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, cy1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x1 + 1, cy1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 2, cy1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cy1, cy2 - cy1, edge_color);
#else
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 150);
    int edge_height = rect.y2-rect.y1-diameter;
    sgl_draw_area_color(surf, cx1, rect.y1, cx2+1, rect.y1+2, edge_color);
    sgl_draw_area_color(surf, cx1, rect.y2-2, cx2+1, rect.y2, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);
        aa_color = sgl_color_mixer(fg_color, bg_color, 255 + f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LTI(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RTI(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LBI(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RBI(surf, cx2, cy2, x, y, aa_color);

        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        sgl_draw_area_color(surf, rect.x1, cy1, rect.x1+2, cy2, edge_color);
        sgl_draw_area_color(surf, rect.x2 - 2, cy1, rect.x2, cy2, edge_color);
    }
#endif
}


void sgl_draw_round_rect_solid_thalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int middle = sgl_figure_circle_path(r, path);
    int height = rect.y2 - cy1;
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));

            sgl_draw_hline(surf, cx1 - path[y], cy1 - y,  (path[y])*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy1 - path[y] + 1, (y)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));

        }
    }
    while(height -- ) {
        sgl_draw_hline(surf, rect.x1 + 1, height + cy1, rect.x2 - rect.x1 - 2, fg_color);
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y1, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, cy1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cy1, rect.y2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = rect.y2 - rect.y1 - r;
    sgl_draw_hline(surf, cx1, rect.y1, cx2 - cx1 + 1, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        sgl_draw_hline(surf, cx1-y, cy1-x+1, cx2 - cx1 + 2*y, fg_color);
        sgl_draw_hline(surf, cx1-x+1, cy1-y, cx2 - cx1 + 2*x - 2, fg_color); 
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        while(edge_height -- ) {
            sgl_draw_hline(surf, rect.x1 + 1, cy1 + edge_height, rect.x2-rect.x1, fg_color);
        }
        sgl_draw_vline(surf, rect.x1, cy1, rect.y2 - rect.y1 - r, edge_color);
        sgl_draw_vline(surf, rect.x2 - 1, cy1, rect.y2 - rect.y1 - r, edge_color);
    }
#endif
}


void sgl_draw_round_rect_solid_bhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    int height = rect.y2 - cy1;
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_hline(surf, cx1 - path[y], cy2 + y - 1,  (path[y])*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy2 + path[y] - 2, (y)*2 + cx2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
        }
    }
    while(height -- ) {
        sgl_draw_hline(surf, rect.x1 + 1, height, rect.x2 - rect.x1 - 1, fg_color);
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 1, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, rect.y1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, rect.y1, rect.y2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = rect.y2 - rect.y1 - r;
    int edge_weigth = rect.x2-rect.x1-diameter;
    sgl_draw_hline(surf, cx1, rect.y2 - 1, edge_weigth + 1, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);
        sgl_draw_point(surf, cx1-x, cy2+y-1, aa_color);
        sgl_draw_point(surf, cx2+x-1, cy2+y-1, aa_color);
        sgl_draw_hline(surf, cx1-y, cy2+x-2, cx2 - cx1 + 2*y, fg_color);
        sgl_draw_hline(surf, cx1-x+1, cy2+y-1,cx2 -cx1 + 2*x - 2, fg_color);
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        do{
            sgl_draw_hline(surf, rect.x1 + 1, cy2 - edge_height, edge_weigth + diameter - 2, fg_color);
        }while(edge_height -- );
        sgl_draw_vline(surf, rect.x1, rect.y1, rect.y2 - rect.y1 - r, edge_color);
        sgl_draw_vline(surf, rect.x2 - 1, rect.y1, rect.y2 - rect.y1 - r, edge_color);
    }
#endif
}


void sgl_draw_round_rect_solid_lhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    int height = cy2 - cy1;
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_hline(surf, cx1 - path[y], cy2 + y - 1,  (path[y]) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - path[y], cy1 - y,  (path[y]) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy1 - path[y] + 1, (y) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, cx1 - y, cy2 + path[y] - 2, (y) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
        }
    }
    while(height -- ) {
        sgl_draw_hline(surf, rect.x1 + 1, height + cy1, rect.x2 - rect.x1 - 1, fg_color);
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y1, rect.x2 - cx1 - 1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 1, rect.x2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, cy1, cy2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = rect.y2 - rect.y1 - diameter;
    sgl_draw_hline(surf, cx1, rect.y1, cx2 - rect.x1, edge_color);
    sgl_draw_hline(surf, cx1, rect.y2-1, cx2 - rect.x1, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);
        sgl_draw_hline(surf, cx1-y, cy1-x+1, cx2 - rect.x1 + y, fg_color);
        sgl_draw_hline(surf, cx1-y, cy2+x-2, cx2 - rect.x1 + y, fg_color);
        sgl_draw_hline(surf, cx1-x+1, cy1-y, cx2 - rect.x1 + x - 1, fg_color);
        sgl_draw_hline(surf, cx1-x+1, cy2+y-1, cx2 - rect.x1 + x - 1, fg_color);
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        do {
            sgl_draw_hline(surf, rect.x1 + 1, cy2 - edge_height, rect.x2 - rect.x1 - 1, fg_color);
        }while(edge_height -- );
        sgl_draw_vline(surf, rect.x1, cy1, cy2 - rect.y1 - r, edge_color);
    }
#endif
}


void sgl_draw_round_rect_solid_rhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    int height = cy2 - cy1;
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_hline(surf, rect.x1, cy2 + y - 1,  (path[y]) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, rect.x1, cy1 - y,  (path[y]) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, rect.x1, cy1 - path[y] + 1, (y) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));

            sgl_draw_hline(surf, rect.x1, cy2 + path[y] - 2, (y) + rect.x2 - cx1, fg_color);
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
        }
    }
    while(height -- ) {
        sgl_draw_hline(surf, rect.x1, height + cy1, rect.x2 - rect.x1 - 1, fg_color);
    }
    sgl_draw_hline(surf, rect.x1, rect.y1, rect.x2 - cx1, edge_color);
    sgl_draw_hline(surf, rect.x1, rect.y2 - 1, rect.x2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cy1, cy2 - cy1, edge_color);
#else
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = rect.y2 - rect.y1 - diameter;
    sgl_draw_hline(surf, rect.x1, rect.y1, cx2 - rect.x1 + 1, edge_color);
    sgl_draw_hline(surf, rect.x1, rect.y2-1, cx2 - rect.x1 + 1, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);
        sgl_draw_hline(surf, rect.x1, cy1-x+1, cx2 - rect.x1 + y, fg_color);
        sgl_draw_hline(surf, rect.x1, cy2+x-2, cx2 - rect.x1 + y, fg_color);
        sgl_draw_hline(surf, rect.x1, cy1-y, cx2 - rect.x1 + x - 1, fg_color);
        sgl_draw_hline(surf, rect.x1, cy2+y-1, cx2 - rect.x1 + x - 1, fg_color);
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        do {
            sgl_draw_hline(surf, rect.x1, cy2 - edge_height, rect.x2 - rect.x1 - 1, fg_color);
        }while(edge_height -- );
        sgl_draw_vline(surf, rect.x2 - 1, cy1, rect.y2 - rect.y1 - diameter, edge_color);
    }
#endif
}


void sgl_draw_round_rect_hollow_thalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int middle = sgl_figure_circle_path(r, path);
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));

            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 -  mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));
        }
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y1, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y1 + 1, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, cy1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x1 + 1, cy1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cy1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 2, cy1, rect.y2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    int edge_height = cy2 - rect.y1;
    sgl_draw_area_color(surf, cx1, rect.y1, cx2+1, rect.y1+2, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        aa_color = sgl_color_mixer(fg_color, bg_color, 255 + f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LTI(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RTI(surf, cx2, cy1, x, y, aa_color);
        
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        sgl_draw_area_color(surf, rect.x1, cy1, rect.x1+2, rect.y2, edge_color);
        sgl_draw_area_color(surf, rect.x2-2, cy1, rect.x2, rect.y2, edge_color);
    }
#endif
}


void sgl_draw_round_rect_hollow_bhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
        }
    }
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 2, cx2 - cx1, edge_color);
    sgl_draw_hline(surf, cx1 + 1, rect.y2 - 1, cx2 - cx1, edge_color);
    sgl_draw_vline(surf, rect.x1, rect.x1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x1 + 1, rect.x1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 2, rect.x1, rect.y2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, rect.x1, rect.y2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 150);
    int edge_height = cy2 - rect.y1;
    sgl_draw_area_color(surf, cx1, rect.y2-2, cx2+1, rect.y2, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);

        aa_color = sgl_color_mixer(fg_color, bg_color, 255 + f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LBI(surf, cx1, cy2, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RBI(surf, cx2, cy2, x, y, aa_color);
        
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        sgl_draw_area_color(surf, rect.x1, rect.y1, rect.x1+2, cy2, edge_color);
        sgl_draw_area_color(surf, rect.x2-2, rect.y1, rect.x2, cy2, edge_color);
    }
#endif
}


void sgl_draw_round_rect_hollow_lhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_point(surf, cx2 + path[y] - 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx2 + path[y] - 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + path[y] - 2, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 -  mix));

            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx2 + y - 1, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
        }
    }
    sgl_draw_hline(surf, rect.x1, rect.y1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, rect.x1, rect.y1 + 1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, rect.x1, rect.y2 - 2, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, rect.x1, rect.y2 - 1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 2, cx1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x2 - 1, cx1, cy2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx1 = rect.x1+r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 150);
    int edge_height = cy2 - rect.y1;
    sgl_draw_area_color(surf, cx1, rect.y1, rect.x2+1, rect.y1+2, edge_color);
    sgl_draw_area_color(surf, cx1, rect.y2-2, rect.x2+1, rect.y2, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LT(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LB(surf, cx1, cy2, x, y, aa_color);

        aa_color = sgl_color_mixer(fg_color, bg_color, 255 + f * 128 / r);
        SGL_RENDER_ROUND_EDGE_LTI(surf, cx1, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_LBI(surf, cx1, cy2, x, y, aa_color);
        
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        sgl_draw_area_color(surf, rect.x1, cy1, rect.x1+2, cy2, edge_color);
    }   
#endif
}


void sgl_draw_round_rect_hollow_rhalf(sgl_surf_t *surf, sgl_rect_t rect, int r, sgl_color_t fg_color, sgl_color_t bg_color)
{
#if (SGL_CONFIG_DRAW_ALGO == 0)
    int mix = 0;
    int16_t path[SGL_CONFIG_DRAW_STACK_MAX];
    memset(path, 0, SGL_CONFIG_DRAW_STACK_MAX*2);
    int cx1 = rect.x1+r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    int middle = sgl_figure_circle_path(r, path);
    sgl_color_t edge_color = sgl_color_mixer(fg_color, bg_color, 128);
    for (int y = 0 ; y < r; y ++) {
        if( y <= middle) {
            mix = (SGL_RENDER_CIRCLE(r, y-1));
            sgl_draw_point(surf, cx1 - path[y], cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy2 + y - 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx1 - path[y], cy1 - y, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - path[y] + 1, cy1 - y, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx1 - y, cy1 - path[y], sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy1 - path[y] + 1, sgl_color_mixer(fg_color, bg_color, 256 - mix));

            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 1, sgl_color_mixer(fg_color, bg_color, mix));
            sgl_draw_point(surf, cx1 - y, cy2 + path[y] - 2, sgl_color_mixer(fg_color, bg_color, 256 - mix));
        }
    }
    sgl_draw_hline(surf, cx1, rect.y1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, cx1, rect.y1 + 1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, cx1, rect.y2 - 2, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_hline(surf, cx1, rect.y2 - 1, rect.x2 - cx1 + 1, edge_color);
    sgl_draw_vline(surf, rect.x1, cx1, cy2 - cy1, edge_color);
    sgl_draw_vline(surf, rect.x1 + 1, cx1, cy2 - cy1, edge_color);
#else 
    int f = 1 - r;
    int diameter = 2*r;
    int ddF_x = 0;
    int ddF_y = - diameter;
    int y = 0;
    int x = r;
    int cx2 = rect.x2-r;
    int cy1 = rect.y1+r;
    int cy2 = rect.y2-r;
    sgl_color_t aa_color, edge_color = sgl_color_mixer(fg_color, bg_color, 150);
    int edge_height = cy2 - rect.y1;
    sgl_draw_area_color(surf, rect.x1, rect.y1, cx2+1, rect.y1+2, edge_color);
    sgl_draw_area_color(surf, rect.x1, rect.y2-2, cx2+1, rect.y2, edge_color);
    while(y < x) {
        if(f >= 0) {
            x--;
            ddF_y += 2;
            f += ddF_y;
        }
        y++;
        ddF_x += 2;
        aa_color = sgl_color_mixer(fg_color, bg_color, - f * 128 / r);
        SGL_RENDER_ROUND_EDGE_RT(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RB(surf, cx2, cy2, x, y, aa_color);

        aa_color = sgl_color_mixer(fg_color, bg_color, 255 + f * 128 / r);
        SGL_RENDER_ROUND_EDGE_RTI(surf, cx2, cy1, x, y, aa_color);
        SGL_RENDER_ROUND_EDGE_RBI(surf, cx2, cy2, x, y, aa_color);
        
        f += ddF_x + 1;
    }
    if ( edge_height > 0) {
        sgl_draw_area_color(surf, rect.x2-2, cy1, rect.x2, cy2, edge_color);
    } 
#endif
}
